package com.dfs.parent.gateway.handler;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;

/**
 * 全局网关异常处理器，优先级高于默认的 ResponseStatusExceptionHandler
 */
@Slf4j
//@Component
//@Primary
public class GlobalGatewayExceptionHandler implements WebExceptionHandler, Ordered {
    public GlobalGatewayExceptionHandler() {
        System.out.println("✅【自定义异常处理器已加载】✅============================");
    }
    /**
     * 设置优先级，数值越小优先级越高
     * 默认的异常处理器 Order 是 0 或 1，所以我们设为 -2 确保优先执行
     */
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 1; // 或直接返回 -2
        // 也可以写成：return -2;
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        System.out.println("🔥 进入自定义异常处理器！=================="); // 临时加的打印
        log.error("🚨 捕获异常: {}, 路径: {}", ex.getMessage(), exchange.getRequest().getURI().getPath());

        // 防止重复写响应
        if (exchange.getResponse().isCommitted()) {
            log.warn("响应已被提交，无法处理异常");
            return Mono.error(ex);
        }

        // 设置默认状态码和消息
        HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
        String message = "系统内部错误";

        // 处理常见的ResponseStatusException（如404 NOT_FOUND）
        if (ex instanceof org.springframework.web.server.ResponseStatusException) {
            ResponseStatusException statusException = (ResponseStatusException) ex;
            status = statusException.getStatus();
            message = ex.getMessage();
        }

        // 如果是找不到路由，也可以特别识别
        if (message.contains("No route found") || status == HttpStatus.NOT_FOUND) {
            status = HttpStatus.NOT_FOUND;
            message = "请求的路由不存在: " + exchange.getRequest().getURI().getPath();
        }

        // 设置响应状态码
        exchange.getResponse().setStatusCode(status);

        // 设置响应头
        exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);

        // 构造返回的JSON体
        String body = String.format(
                "{\"timestamp\": \"%s\", \"status\": %d, \"error\": \"%s\", \"path\": \"%s\"}",
                java.time.LocalDateTime.now(),
                status.value(),
                message,
                exchange.getRequest().getURI().getPath()
        );

        // 写出响应
        return exchange.getResponse().writeWith(
                Mono.just(exchange.getResponse().bufferFactory().wrap(body.getBytes()))
        );
    }
}